package com.satyam.smooth.domain;

import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

@Entity
public class Purchase implements Serializable {

    private static final long serialVersionUID = 1L;

    public Purchase() {
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private Long billNo;

    @Column(nullable = false)
    private Date onDate;

    @ManyToOne(optional = false)
    private User user;

    @ManyToOne(optional = false)
    private Vendor vendor;

    @Column(nullable = false)
    private BigDecimal vat = BigDecimal.ZERO;

    @Column(nullable = false)
    private BigDecimal discount = BigDecimal.ZERO;

    @Column(nullable = false)
    private BigDecimal total = BigDecimal.ZERO;

    @Column(nullable = false)
    private BigDecimal grandTotal = BigDecimal.ZERO;

    @OneToMany(mappedBy = "purchase", fetch = FetchType.LAZY, cascade = {CascadeType.ALL})
    private Set<PurchaseDetail> purchaseDetails = new HashSet<>();

    @Column(nullable = true)
    private String remark;
    
    public void addPurchaseDetail(PurchaseDetail purchaseDetail){
        purchaseDetail.setPurchase(this);
        getPurchaseDetails().add(purchaseDetail);
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Long getBillNo() {
        return billNo;
    }

    public void setBillNo(Long billNo) {
        this.billNo = billNo;
    }

    public Date getOnDate() {
        return onDate;
    }

    public void setOnDate(Date onDate) {
        this.onDate = onDate;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public Vendor getVendor() {
        return vendor;
    }

    public void setVendor(Vendor vendor) {
        this.vendor = vendor;
    }

    public BigDecimal getVat() {
        return vat;
    }

    public void setVat(BigDecimal vat) {
        this.vat = vat;
    }

    public BigDecimal getDiscount() {
        return discount;
    }

    public void setDiscount(BigDecimal discount) {
        this.discount = discount;
    }

    public BigDecimal getTotal() {
        return total;
    }

    public void setTotal(BigDecimal total) {
        this.total = total;
    }

    public BigDecimal getGrandTotal() {
        return grandTotal;
    }

    public void setGrandTotal(BigDecimal grandTotal) {
        this.grandTotal = grandTotal;
    }

    public Set<PurchaseDetail> getPurchaseDetails() {
        return purchaseDetails;
    }

    public void setPurchaseDetails(Set<PurchaseDetail> purchaseDetails) {
        this.purchaseDetails = purchaseDetails;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    public void calculateGrandTotal() {
        for (PurchaseDetail pd : getPurchaseDetails()) {
            this.total.add(pd.getTotal());
        }

        //grandTotal = grandTotal * (1 - discount/100);
        this.grandTotal.add(this.total);
        this.grandTotal.multiply(new BigDecimal(BigInteger.ONE).subtract(this.discount.divide(new BigDecimal(100))));

        //grandTotal = grandTotal + (1 + vat/100);
        this.grandTotal.multiply(new BigDecimal(BigInteger.ONE).add(this.vat.divide(new BigDecimal(100))));
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
    }

}
